
MAKE = make
MAKEFILE_DIR = $(PWD)

VERILATOR = verilator
VERI_FLAGS += +vcd
VERI_CFLAGS +=

PROGRAM ?= hello_world
VERI_BUILD_DIR ?= veri_build
RTL_MANIFEST := manifest.flist
VERI_CUSTOM_DIR ?= $(PWD)/tests/custom_programs
BIN_TO_MEM_TOOL ?= $(PWD)/tools/BinToMem_CLI.py
SIM_MEM ?= sim_mem.bin

ifeq ($(findstring +vcd,$(VERI_FLAGS)),+vcd)
VERI_TRACE = "--trace"
VERI_CFLAGS += "-DVCD_TRACE"
else
VERI_TRACE =
endif

TBSRC_DIR = $(MAKEFILE_DIR)/tb
TBSRC_VERI := $(TBSRC_DIR)/tb_top_verilator.sv

.DEFAULT_GOAL := all

.PHONY: all
all: rtl_compile sim_run

.PHONY: rtl_compile
rtl_compile:
	$(VERILATOR) --cc --sv --exe \
		$(VERI_TRACE) \
		--Wno-lint --Wno-UNOPTFLAT \
		--Wno-MODDUP --top-module \
		tb_top_verilator \
		-f $(RTL_MANIFEST) \
		$(TBSRC_VERI) \
		$(TBSRC_DIR)/tb_top_verilator.cpp --Mdir $(VERI_BUILD_DIR) \
		-CFLAGS "-std=gnu++11 $(VERI_CFLAGS)"
	$(MAKE) -C $(VERI_BUILD_DIR) -f Vtb_top_verilator.mk

.PHONY: sim_run
sim_run: $(VERI_CUSTOM_DIR)/$(PROGRAM)/$(SIM_MEM)
	./$(VERI_BUILD_DIR)/Vtb_top_verilator "+firmware=$(VERI_CUSTOM_DIR)/$(PROGRAM)/$(SIM_MEM)"

$(VERI_CUSTOM_DIR)/$(PROGRAM)/$(SIM_MEM):
	$(MAKE) -C $(VERI_CUSTOM_DIR)/$(PROGRAM) clean
	$(MAKE) -C $(VERI_CUSTOM_DIR)/$(PROGRAM)
	python3 $(BIN_TO_MEM_TOOL) $(VERI_CUSTOM_DIR)/$(PROGRAM)/$(PROGRAM).bin $@

.PHONY: clean
clean:
	rm -rf *.vcd *.log $(VERI_BUILD_DIR)
